package com.ztgf.sms.common;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.xuanwu.mos.MessageData;
import com.xuanwu.mos.PostMsg;
import com.xuanwu.mos.PostMsgBuilder;
import com.xuanwu.mos.common.entity.Account;
import com.xuanwu.mos.common.entity.AccountInfo;
import com.xuanwu.mos.common.entity.GsmsResponse;
import com.xuanwu.mos.common.entity.MTPack;
import com.xuanwu.mos.common.util.Interceptor;
import com.ztgf.common.constant.Result;
import com.ztgf.common.constant.ZTConstant;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.common.utils.AESUtil;
import com.ztgf.common.utils.SignUtils;
import com.ztgf.sms.models.bo.SmsNoModelBO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.*;

/*
   玄武短信配置
 */
@Component
@Slf4j
public class GetXWPostMsg {
    @Value(value = "${sms.pm.short_conn_mode}")
    private String short_conn_mode; //设置是否以短连接方式交互, 建议为false(即长连接以提高性能)

    @Value(value = "${sms.gw.host}")
    private String gw_host; //发送消息的接口ip

    @Value(value = "${sms.gw.port}")
    private String gw_port; //发送消息的接口port

    @Value(value = "${sms.ws.host}")
    private String ws_host; //上行的接口ip

    @Value(value = "${sms.ws.port}")
    private String ws_port; //上行的接口port

    @Value(value = "${sms.account}")
    private String sms_account; //短信账号

    @Value(value = "${sms.password}")
    private String sms_password; //短信密码

    @Value(value = "${sms.timeout}")
    private String sms_timeout; //验证码过期时间（秒）

    public PostMsg MsgClient(){
        final PostMsg pm = PostMsgBuilder.getInstance() // 保持单例模式
                .setShortConnMode(Boolean.getBoolean(short_conn_mode)) // 设置是否以短连接方式交互, 建议为false(即长连接以提高性能)
                .setSoTimeout(15000) // Socket读写超时时间(毫秒)
                .setMaxConnForMT(2) // 每个账号MT最大并发连接数(下发), 若发送量较大可调整为3-7
                .setMaxConnForMO(2) // 每个账号MO最大并发连接数(获取上行/状态报告)
                .build();

        pm.getGwHost().setHost(gw_host, Integer.valueOf(gw_port)); // 设置网关的IP和port, 用于发送信息
        pm.getWsHost().setHost(ws_host, Integer.valueOf(ws_port)); // 设置网关的IP和port, 用于获取账号信息、上行、状态报告

        // 网络耗时调试功能(仅需要时配置)
        pm.setInterceptor(new Interceptor() {
            public void beforeMtSend(long waitConnTime, long loginTime, MTPack pack) {
                // 加上自定义的日志输出
                System.out.println("MT before send [" + pack.getBatchID()
                        + "] wait:" + waitConnTime + ", login:" + loginTime + ", now:" + System.currentTimeMillis());
            }
        });

        // 下发失败内部自动重试(仅需要时配置)
        pm.getGwHost().setRetryTimes(1); // 重试次数
        pm.getGwHost().setRetryInterval(500); // 重试间隔: 毫秒

        // 设置代理服务器(仅需要时配置)
        // settingProxyServer(pm);

//        Account account = new Account("ztgc@ztgc", "ZepW5dmz"); // 单账号
        // account.setSessionKey("16位长度的英文或数字密钥"); // 配置通信安全密钥对敏感数据加密(用于高安全性要求的场景, 同时增加少量性能损耗)

//        doSendSms(pm, account); // 短信下行
//		doSendMms(pm, account); // 彩信下行

//		doGetAccountInfo(pm, account); // 获取账号信息
//		doModifyPwd(pm, account); // 修改密码

//		doGetMos(pm, account); // 获取上行信息
//		doGetReports(pm, account); // 获取状态报告

        return pm;
    }

    public GsmsResponse sendSMS(String mobile, String content) throws Exception{
//        Account account = new Account(sms_account, sms_password); // 单账号
//        MTPack pack = new MTPack();
//        pack.setBatchID(UUID.randomUUID());
//        pack.setBatchName("短信测试批次");
//        pack.setMsgType(MTPack.MsgType.SMS);
//        //pack.setBizType(2); // 设置业务类型
//        pack.setDistinctFlag(true); // 是否进行号码去重
//        ArrayList<MessageData> msgs = new ArrayList<MessageData>();
//
//        /** 单发, 一号码一内容 */
//        pack.setSendType(MTPack.SendType.GROUP);
//        msgs.add(new MessageData(mobile, content));
//        pack.setMsgs(msgs);
//
//        /** 群发, 多号码同一内容 */
//		/*pack.setSendType(MTPack.SendType.MASS);
//		String content = "短信群发测试";
//		msgs.add(new MessageData("137000000X1", content));
//		msgs.add(new MessageData("137000000X2", content));
//		pack.setMsgs(msgs);*/
//
//        /** 组发, 多号码多内容 */
//		/*pack.setSendType(MTPack.SendType.GROUP);
//		msgs.add(new MessageData("137000000X1", "短信组发测试1"));
//		msgs.add(new MessageData("137000000X2", "短信组发测试2"));
//		pack.setMsgs(msgs);*/
//
//        /** 使用模板方式发送, 设置模板编号(静态模板将以模板内容发送; 动态模板需要发送变量值) */
//		/*pack.setTemplateNo("8973febf65e144d492d070dc8c55b46c");
//		msgs.add(new MessageData("137000000X1", "[]")); // 1. 静态模板(不需要传变量, 空数组即可)
//		msgs.add(new MessageData("137000000X2", "[\"测试用户\",\"123456\"]")); // 2. 动态模板设置依次替换的参数
//		pack.setMsgs(msgs);
//		*/
//
//        GsmsResponse resp = MsgClient().post(account, pack);
//        return resp;
         return this.smsNormalSend(mobile,content);
    }

    public GsmsResponse sendBatchSMS(HashMap<String, String> batchMap) throws Exception{
//        Account account = new Account(sms_account, sms_password); // 单账号
//        MTPack pack = new MTPack();
//        pack.setBatchID(UUID.randomUUID());
//        pack.setBatchName("短信测试批次");
//        pack.setMsgType(MTPack.MsgType.SMS);
//        pack.setDistinctFlag(true); // 是否进行号码去重
//        ArrayList<MessageData> msgs = new ArrayList<MessageData>();
//
//        /** 群发, 多号码同一内容 */
//        pack.setSendType(MTPack.SendType.MASS);
//        String content = batchMap.get("content");
//        String[] phones = batchMap.get("mobile").split(",");
//        for (String phone : phones){
//            msgs.add(new MessageData(phone, content));
//        }
//        pack.setMsgs(msgs);
//
//        GsmsResponse resp = MsgClient().post(account, pack);
//        return  resp;


        String content = batchMap.get("content");
        String[] phones = batchMap.get("mobile").split(",");
        return this.smsNormalList(Arrays.asList(phones),content);
    }

    //对接业务中台单个普通短信服务
    public GsmsResponse smsNormalSend(String mobile, String content) {
        log.info("业务中台短信发送-----------------------------------start-----"+mobile+"------------content"+content);
        SmsNoModelBO smsNoModel = new SmsNoModelBO();
        smsNoModel.setOperatorId(ZTConstant.ZT_CONFIG_OPERATORID);
        smsNoModel.setMobile(mobile);
        smsNoModel.setContent(content);
        String jsonStr = JSONUtil.toJsonStr(smsNoModel);
        int i = RandomUtils.nextInt(1000000, 10000000);
        String nonceStr = "" + System.currentTimeMillis() + i;
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = AESUtil.encrypt(jsonStr, ZTConstant.ZT_CONFIG_SMS_SECRET);
        String sign = SignUtils.createSign(ZTConstant.ZT_CONFIG_APPID, timestamp, nonceStr, key, ZTConstant.ZT_CONFIG_SMS_SECRET);
        String res = HttpUtil.createPost(ZTConstant.ZT_CONFIG_MESSAGE_SENDNOMODEL_PATH)
                .header("appId", ZTConstant.ZT_CONFIG_APPID)
                .header("nonce", nonceStr)
                .header("timestamp", timestamp)
                .header("sign", sign)
                .header("TENANT-ID",ZTConstant.ZT_CONFIG_TENANTID)
                .form("data",key)
                .execute().body();
        log.info("业务中台短信发送-----------------------------------end--------------"+res);
        GsmsResponse resp = new GsmsResponse();
        resp.setResult(1);
        resp.setMessage(CodeEnum.FAIL.getMsg());
        Object code = JSONObject.parseObject(res).get("code");
        if (ObjectUtil.equals(code, 0)) {
            resp.setResult(0);
            resp.setMessage(CodeEnum.SUCCESS.getMsg());
            return resp;
        }
        return resp;
    }

    //对接业务中台单个普通短信服务
    public GsmsResponse smsNormalList(List<String> mobiles, String content) {
        log.info("业务中台批量短信发送-----------------------------------start---------"+mobiles.toString());
        SmsNoModelBO smsNoModel = new SmsNoModelBO();
        smsNoModel.setOperatorId(ZTConstant.ZT_CONFIG_OPERATORID);
        smsNoModel.setMobiles(mobiles);
        smsNoModel.setContent(content);
        String jsonStr = JSONUtil.toJsonStr(smsNoModel);
        int i = RandomUtils.nextInt(1000000, 10000000);
        String nonceStr = "" + System.currentTimeMillis() + i;
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        String key = AESUtil.encrypt(jsonStr, ZTConstant.ZT_CONFIG_SMS_SECRET);
        String sign = SignUtils.createSign(ZTConstant.ZT_CONFIG_APPID, timestamp, nonceStr, key, ZTConstant.ZT_CONFIG_SMS_SECRET);
        String res = HttpUtil.createPost(ZTConstant.ZT_CONFIG_MESSAGE_SENDNOMODELLIST_PATH)
                .header("appId", ZTConstant.ZT_CONFIG_APPID)
                .header("nonce", nonceStr)
                .header("timestamp", timestamp)
                .header("sign", sign)
                .header("TENANT-ID",ZTConstant.ZT_CONFIG_TENANTID)
                .form("data",key)
                .execute().body();
        log.info("业务中台短信发送-----------------------------------end--------------"+res);
        GsmsResponse resp = new GsmsResponse();
        resp.setResult(1);
        resp.setMessage(CodeEnum.FAIL.getMsg());
        Object code = JSONObject.parseObject(res).get("code");
        if (ObjectUtil.equals(code, 0)) {
            resp.setResult(0);
            resp.setMessage(CodeEnum.SUCCESS.getMsg());
            return resp;
        }
        return resp;
    }

    public AccountInfo doGetAccountInfo () throws Exception{
        Account account = new Account(sms_account, sms_password); // 单账号
        AccountInfo accountInfo = MsgClient().getAccountInfo(account);
        return accountInfo;
    }
}
